package com.star.ms.admin.dao.impl.user;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.star.ms.admin.dao.user.UserDAO;
import com.star.ms.common.dao.mapper.user.UrMapper;
import com.star.ms.common.dao.mapper.user.UserMapper;
import com.star.ms.common.enums.RoleStatusEnum;
import com.star.ms.common.entity.api.Captcha;
import com.star.ms.common.entity.product.Product;
import com.star.ms.common.entity.user.Ur;
import com.star.ms.common.entity.user.User;
import com.star.ms.common.vo.UserProvinceCountVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Date;
import java.util.List;
import java.util.Map;

@Component
public class UserDAOImpl implements UserDAO {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UrMapper userRoleMapper;
    // 使用事物管理
    @Transactional
    public User insertUser(User newUser) {
        int add = userMapper.insert(newUser);
        if(add < 1) return null;

        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsercode, newUser.getUsercode())
                .eq(User::getPassword, newUser.getPassword());
        // 根据账号密码查询
        User user = userMapper.selectOne(wrapper);
        // 添加创建信息、设置用户角色

        if(user != null){
            // 添加创建信息
            user.setCreateTime(new Date(System.currentTimeMillis()));
            Ur userRole = new Ur(
                    null,
                    user.getId(),
                    RoleStatusEnum.COMMON_USER.getId());
            // 设置用户角色
            add = userRoleMapper.insert(userRole);
            // 操作未发生影响，直接返回 null
            if(add < 1) throw new RuntimeException("插入用户角色失败!");
        }
        return user;
    }

    public User selectByCodeAndPassword(String code, String password){
        return userMapper.selectByCodeAndPassword(code, password);
    }

    @Autowired
    private RedisDAOImpl redisDAO;
    @Override
    public boolean insertCaptcha(User user, Captcha captcha) {
        // 拼接待插入的 key
        String key = "captcha:" + user.getUsercode();
        String value = captcha.getInfo();
        // 插入前先删除
        redisDAO.del(key);
        redisDAO.set(key, value, 60);
        return redisDAO.get(key).equals(value);
    }

    /**
     * 返回指定用户的验证码，包括过期时间
     * @param user 指定用户
     * @return 查询到的验证码信息
     */
    @Override
    public Captcha selectCaptcha(User user) {
        assert user.getUsercode() != null;
        String key = "captcha:" + user.getUsercode();
        return new Captcha(redisDAO.get(key),null, redisDAO.ttl(key));
    }

    /**
     * 根据用户的账号查询用户
     * @param userCode
     * @return
     */
    @Override
    public User selectByCode(String userCode) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsercode, userCode);
        return userMapper.selectOne(wrapper);
    }

    @Override
    public boolean updateSelective(User user) {
        return userMapper.updateById(user) == 1;
    }

    @Override
    public int updateImgByCode(String code, String imgUrl) {
        return userMapper.updateImgByCode(code, imgUrl);
    }

    @Override
    public List<User> selectWithRoleByMap(Map<String, Object> condition) {
        return userMapper.selectByMapWithRole(condition);
    }

    @Override
    public IPage<Product> selectListWithRoleBySome(Page<Object> page, Map<String, Object> condition) {
        return userMapper.selectListWithRoleBySome(page, condition);
    }

    @Override
    public List<User> selectWithRoleByIds(List<Long> ids) {
        return userMapper.selectListWithRoleByIds(ids);
    }

    @Override
    public int updateImgById(Long userId, String imgUrl) {
        return userMapper.updateImgById(userId, imgUrl);
    }

    @Override
    public int selectMaxUserId() {
        return userMapper.selectMaxUserId();
    }

    public User selectById(Long userId) {
        QueryWrapper<User> wrapper = new QueryWrapper<User>();
        wrapper.eq("user_id", userId);
        return userMapper.selectOne(wrapper);
    }


    @Override
    public List<UserProvinceCountVo> selectListWithProvinceCount() {
        return userMapper.selectListWithProvinceCount();
    }

    @Override
    public boolean updatePassword(User user) {
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id", user.getId()).set("user_password", user.getPassword());
        return userMapper.update(null, wrapper) == 1;
    }
}
